﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.Linq;

namespace BuzzX8.Xmpp.StreamElements.Stanza
{
    public class RosterItem : StreamElement
    {
        private SubscriptionStatus? subscriptionStatus;
        private ICollection<string> groups;

        public RosterItem(string itemName) : this(itemName, null)
        {}

        public RosterItem(string itemName, JID jid) : this(itemName, jid, null)
        {
        }

        public RosterItem(string itemName, JID jid, SubscriptionStatus? subscription) : base("item")
        {
            groups = new List<string>();
            ItemName = itemName;
            Jid = jid;
            Subscription = subscription;
        }

        public string ItemName
        {
            get { return (string) Attributes["name"]; }
            set { Attributes["name"] = value; }
        }

        public JID Jid
        {
            get { return (JID) Attributes["jid"]; }
            set { Attributes["jid"] = value; }
        }

        public ICollection<string> Groups
        {
            get { return groups; }
        }

        public SubscriptionStatus? Subscription
        {
            get { return subscriptionStatus; }
            set
            {
                Attributes["subscription"] = GetValueForSubscriptionAttribute(value);
                subscriptionStatus = value;
            }
        }

        private string GetValueForSubscriptionAttribute(SubscriptionStatus? subscriptionStatus)
        {
            if (subscriptionStatus == null) return "";
            switch (subscriptionStatus)
            {
                case SubscriptionStatus.None:
                    return "none";

                case SubscriptionStatus.To:
                    return "to";

                case SubscriptionStatus.From:
                    return "from";

                case SubscriptionStatus.Both:
                    return "both";

                case SubscriptionStatus.Remove:
                    return "remove";

                default:
                    throw new NotImplementedException();
            }
        }

        public void AddGroups(params string[] groupNames)
        {
            foreach (string groupName in groupNames) Groups.Add(groupName);
        }

        protected override void WritePayload(XmlWriter writer)
        {
            foreach (string groupName in Groups)
            {
                writer.WriteElementString("group", groupName);
            }
        }

        public override bool Equals(object obj)
        {
            if (obj == null) return false;
            if (obj.GetType() != typeof(RosterItem)) return false;
            RosterItem rosterItem = (RosterItem) obj;

            return ItemName == rosterItem.ItemName &&
                   Jid.Equals(rosterItem.Jid) &&
                   Subscription == rosterItem.Subscription &&
                   Groups.SequenceEqual(rosterItem.Groups);
        }
    }
}
